package com.huaxin.dss2.message;

import com.google.common.collect.Maps;
import com.huaxin.dss2.data.DataService;
import com.huaxin.dss2.data.NewSmallStation.SDataValue;
import com.huaxin.dss2.message.bean.DataMsgBean;
import com.huaxin.dss2.message.exception.SaveRealDataException;
import com.huaxin.dss2.util.ScheduledValue;
import com.huaxin.dss2.util.SpringUtils;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.cache.Cache;
import org.springframework.cache.ehcache.EhCacheCacheManager;

/**
 * 消息处理
 * Created by HX-119 on 2014/6/27.
 */
@Slf4j
public class MessageParser {


    private static final String STATION_ID = "StationID";
    private static final String ISEQ = "iSeq";
    private static final String SEND_DATE = "SendDate";
    private static final String ERROR_INFO = "Errorinfo";
    private static final String STATE = "STATE";


    private static final Cache DATA_DATE_CACHE = SpringUtils.getBean(EhCacheCacheManager.class)
        .getCache("dataDate");

    private static final DataService dataService = SpringUtils.getBean(DataService.class);


    private MessageParser() {

    }

    /**
     * 厂级格式化消息
     * @param text 消息内容
     * @return 格式化结果
     */
    public static DataMsgBean parse(String text) {
        String[] lineTextArray = text.split("\n");
        DataMsgBean dataMsgBean = new DataMsgBean();
        Map<String, Double> dataMap = dataMsgBean.getDataMap();
        Map<String, Integer> stateMap = dataMsgBean.getStateMap();
        for (String lineText : lineTextArray) {
            lineText = lineText.trim();
            if (!lineText.contains("*")) {
                continue;
            }
            String[] keyValue = lineText.split("\\*");
            String key = keyValue[0];
            String value = keyValue.length == 2 ? keyValue[1] : null;

            switch (key) {
                case STATION_ID:
                    dataMsgBean.setStationId(value);
                    break;
                case SEND_DATE:
                    dataMsgBean.setSendDate(value);
                    break;
                case ISEQ:
                    dataMsgBean.setISeq(Integer.valueOf(value));
                    break;
                case ERROR_INFO:
                    dataMsgBean.setErrorInfo(value);
                    break;
                case STATE:
                    dataMsgBean.setErrorInfo(value);
                    break;
                default:
                    String fullDataCode = dataMsgBean.getStationId() + "_" + key.trim();
                    if (null != value) {
                        if (value.contains("e") || value.contains("E")) {
                            if (value.contains("e") && value.split("e").length < 2) {
                                value = value + "0";
                            }
                            if (value.contains("E") && value.split("E").length < 2) {
                                value = value + "0";
                            }
                            BigDecimal bg = new BigDecimal(value);
                            double doubleValue = bg.doubleValue();
                            dataMap.put(fullDataCode, doubleValue);
                            stateMap
                                .put(fullDataCode, dataService.getState(fullDataCode, doubleValue));
                        } else {
                            double doubleValue = Double.valueOf(value);
                            dataMap.put(fullDataCode, doubleValue);
                            stateMap
                                .put(fullDataCode, dataService.getState(fullDataCode, doubleValue));
                        }
                    }
            }
        }
        try {
            Date date = parseDataDate(dataMsgBean.getSendDate(), dataMsgBean.getISeq());
            dataMsgBean.setDataTime(date.getTime());
        } catch (ParseException e) {
            log.error("数据日期解析失败 SendDate:{} iseq:{}", dataMsgBean.getSendDate(),
                dataMsgBean.getISeq());
        }
        return dataMsgBean;
    }


    /**
     * 站点数据队列转换
     * @return dataMsgBean
     * @throws SaveRealDataException SaveRealDataException
     */
    public static DataMsgBean parseSmall(String stationCode) throws SaveRealDataException {

        if (ScheduledValue.DATA_VALUE_MAP.size() == 0) {
            return new DataMsgBean();
        }

        DataMsgBean dataMsgBean = new DataMsgBean();
        try {
            Map<String, SDataValue> dataValueMap = Maps.newHashMap(ScheduledValue.DATA_VALUE_MAP);
            Map<String, Double> dataMap = dataMsgBean.getDataMap();
            Map<String, Integer> stateMap = dataMsgBean.getStateMap();
            Date date = new Date();
            int i = 0;

            for (Map.Entry<String, SDataValue> entry : dataValueMap.entrySet()) {
                String dataCode = entry.getKey();
                if (dataCode.split("_").length != 3) {
                    continue;
                }

                if (!dataCode.split("_")[0].equals(stationCode)) {
                    continue;
                }
                if (i == 0) {
                    dataMsgBean.setStationId(dataCode.split("_")[0]);
                    dataMsgBean.setSendDate(new SimpleDateFormat("yyyy-MM-dd").format(date));
                    dataMsgBean.setErrorInfo("DATAOK");
                    dataMsgBean.setDataTime(date.getTime());
                    i++;
                }
                SDataValue sDataValue = dataValueMap.get(dataCode);
                dataMap.put(dataCode, sDataValue.getValue());
                stateMap.put(dataCode, 0);
            }
        } catch (Exception e) {
            log.error("发生异常",e);
        }

        return dataMsgBean;
    }


    /**
     * 格式化数据日期
     * @param sendDate
     * @param iseq
     * @return
     * @throws ParseException
     */
    private static Date parseDataDate(String sendDate, Integer iseq) throws ParseException {
        Cache.ValueWrapper cacheValue = DATA_DATE_CACHE.get(sendDate);
        Date date = null;
        if (cacheValue == null) {
            date = DateUtils.parseDate(sendDate, "yyyy-MM-dd");
            DATA_DATE_CACHE.put(sendDate, date);
        } else {
            date = (Date) cacheValue.get();
        }
        return DateUtils.addSeconds(date, iseq * 5);
    }

}
